
//
// 110124 - AH - Created.
//

package org.soekrat.engine;

import java.util.ArrayList;
import java.util.List;

import org.soekrat.engine.event.SoekratChangeEvent;
import org.soekrat.engine.event.SoekratChangeListener;

/**
 * <p>
 *   Base class for objects that are part of the engine layer of Soekrat. 
 * </p>
 * <p>
 *   It is not required that all objects part of the engine needs to extend
 *   this class but will be an implementation advantage if publishing
 *   {@link SoekratChangeEvent}s.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC) 
 */
public abstract class SoekratEngineObject 
{
  private transient List<SoekratChangeListener> m_listeners=null;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  protected SoekratEngineObject(){}
  
  private final SoekratChangeEvent m_event=new SoekratChangeEvent(this);
  
  /**
   * <p>
   *   Adds
   *   {@link SoekratChangeListener}.
   * </p>
   * @param l Listener to add.
   */
  public final synchronized void addSoekratChangeListener(
    SoekratChangeListener l)
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
    
    if (m_listeners==null) m_listeners=new ArrayList<SoekratChangeListener>();
    if (!m_listeners.contains(l)) m_listeners.add(l);
  }
  
  /**
   * <p>
   *   Removes
   *   {@link SoekratChangeListener}.
   * </p>
   * @param l Listener to remove.
   */
  public final synchronized void removeSoekratChangeListener(
    SoekratChangeListener l)
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
    
    if (m_listeners==null) return;
    m_listeners.remove(l);
  }
  
  protected final void fire()
  {
    if (m_listeners==null) return;
    
    SoekratChangeListener[] l=SoekratChangeListener.E_ARRAY;
    synchronized(this){ l=m_listeners.toArray(l); }
    for (SoekratChangeListener curr : l) curr.changed(m_event);
  }
  
}
